const { ccclass, property } = cc._decorator;

@ccclass
export default class BirdControl extends cc.Component {
  // 生命值
  hp = 1;

  // 目标位置
  targetPos: cc.Vec2 = null;

  // 最大目标点
  private _maxTargetPos: cc.Vec2 = null;

  // 速度
  speed = 300;

  // 游戏结束的回调
  dieCallback?: () => void;

  // 加分回调
  addScoreCallback?: () => void;

  protected start(): void {
    this._countMaxTargetPos();
    this._setStartPos();
    this.fly();
  }

  /**
   * 计算最大目标点 (canvas 的锚点无法修改...)
   * @returns cc.Vec2
   */
  private _countMaxTargetPos() {
    // 目标点X轴
    const maxTargetX = cc.view.getVisibleSize().width / 2 + this.node.width / 2;
    // 目标点Y轴
    const maxTargetY =
      cc.view.getVisibleSize().height / 2 + this.node.height / 2;
    this._maxTargetPos = cc.v2(maxTargetX, maxTargetY);
    return this._maxTargetPos;
  }

  /**
   * 随机设置开始位置
   */
  private _setStartPos() {
    const startX = this._maxTargetPos.x - 150;
    this.node.x = this._random(-1 * startX, startX);
    this.node.y = this._maxTargetPos.y * -1;
  }

  fly() {
    // 随机目标点
    this.targetPos = cc.v2(
      this._random(-1 * this._maxTargetPos.x, this._maxTargetPos.x),
      this._maxTargetPos.y
    );
    // 反转精灵
    if (this.targetPos.x < this.node.x) {
      this.node.scaleX = -1;
    }
    // 速度 * 时间 = 距离
    const move = cc.moveTo(
      (this.targetPos.y - this.node.y) / this.speed,
      this.targetPos
    );

    cc.tween(this.node)
      .to((this.targetPos.y - this.node.y) / this.speed, {
        x: this.targetPos.x,
        y: this.targetPos.y,
      })
      // 当前面的动作都执行完毕后才会调用这个回调函数
      .call(() => {
        // 游戏结束
        this.dieCallback?.();
        this.node.destroy();
      })
      .start();

    // 如果触摸了精灵，就下落
    this.node.on(cc.Node.EventType.TOUCH_START, (event) => {
      // 如果还活着才能点
      if (this.hp > 0) {
        this.hp--;

        if (this.hp <= 0) {
          // 停止所有的动作
          this.node.stopAllActions();
          // 执行死亡的动画
          this.getComponent(cc.Animation).play("die");
          // 向下掉落
          // 向下掉落的目标位置 Y
          const downTargetY = (this._maxTargetPos.y + 30) * -1;

          cc.tween(this.node)
            .to((this.node.y - downTargetY) / (this.speed * 2), {
              x: this.node.x,
              y: downTargetY,
            })
            .call(() => {
              this.node.destroy();
            })
            .start();

          // 加分
          this.addScoreCallback?.();
        } else {
          // 这里其实可以执行一下特效...，但是目前只有一滴血,所以暂时没有其他特性
        }
      }
    });
  }

  private _random(min: number, max: number) {
    return Math.random() * (max - min) + min;
  }
}
